/****************************************************************************
*					SimpleParameterLearning
*
*	Description:	The most general (simple) appoach to parameter learning:
*					- using L-BFGS for optimization of the functional
*					- Maximum Likelihood Estimation
*
****************************************************************************/

#ifndef _SimpleParameterLearning_H
#define _SimpleParameterLearning_H

#include <vector>
#include "lbfgs.h"
#include "PGMStruct.h"
#include "DataSet.h"
#include "ParameterLearning.h"
#include "Inference.h"

class SimpleParameterLearning : public ParameterLearning {
  private:

  protected:

	  /* DATA */
	  // Parameters of the algorithm for objective function minimization
	lbfgs_parameter_t lbfgsParams;

	  /* FUNCTIONS */
	  // Function to calculate value of the objective and its gradient
	static lbfgsfloatval_t calcValueAndGradient (void *instance, const lbfgsfloatval_t *x, lbfgsfloatval_t *g, const int n, const lbfgsfloatval_t step);

	  // Function to printout progress of the optimization process
	static int printoutProgress (void *instance, const lbfgsfloatval_t *x, const lbfgsfloatval_t *g, const lbfgsfloatval_t fx, const lbfgsfloatval_t xnorm, const lbfgsfloatval_t gnorm, const lbfgsfloatval_t step, int n, int k, int ls );

	  // Function to calculate empirical probability of a features 

  public:

	  // Standard constructor
	SimpleParameterLearning(void);
      
	  // Standard destructor
    ~SimpleParameterLearning();

      // Learns weights values for a given PGM given the data set and the algorithm for running inference
	float learn (DataSet& dataSet, PGMStruct& pgmStruct, Inference* inference);

	  // Sets object patameters from environment
	int setParameters (Environment &environment);
	
}; // end of class


// Structure to pass PGMStruct and dataSet to calcValueAndGradient function as one pointer
struct PGMandDataSet {
	PGMStruct* pgmStruct;
	DataSet* dataSet;
	Inference* inference;
}; // end of struct

#endif // _SimpleParameterLearning_H
